using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

namespace MaterialUI
{
	[ExecuteInEditMode]
	[AddComponentMenu("MaterialUI/Vector Image", 50)]
	public class VectorImage : Text
	{
		public enum SizeMode
		{
			Manual,
			MatchWidth,
			MatchHeight,
			MatchMin,
			MatchMax
		}

		[SerializeField]
		private float m_Size = 48f;

		[SerializeField]
		private float m_ScaledSize;

		[SerializeField]
		private SizeMode m_SizeMode = SizeMode.MatchMin;

		[SerializeField]
		private MaterialUIScaler m_MaterialUiScaler;

		[SerializeField]
		private VectorImageData m_VectorImageData = new VectorImageData();

		private bool m_DisableDirty;

		private float m_LocalScaleFactor;

		private readonly UIVertex[] m_TempVerts = new UIVertex[4];

		private DrivenRectTransformTracker m_Tracker = default(DrivenRectTransformTracker);

		public float size
		{
			get
			{
				return m_Size;
			}
			set
			{
				m_Size = value;
				RefreshScale();
			}
		}

		public float scaledSize => m_ScaledSize;

		public SizeMode sizeMode
		{
			get
			{
				return m_SizeMode;
			}
			set
			{
				m_SizeMode = value;
				m_Tracker.Clear();
				RefreshScale();
				SetLayoutDirty();
			}
		}

		public MaterialUIScaler materialUiScaler
		{
			get
			{
				if (m_MaterialUiScaler == null)
				{
					m_MaterialUiScaler = MaterialUIScaler.GetParentScaler(base.transform);
				}
				return m_MaterialUiScaler;
			}
		}

		public VectorImageData vectorImageData
		{
			get
			{
				return m_VectorImageData;
			}
			set
			{
				m_VectorImageData = value;
				updateFontAndText();
				RefreshScale();
			}
		}

		public override float preferredWidth => size;

		public override float minWidth => -1f;

		public override float flexibleWidth => -1f;

		public override float preferredHeight => size;

		public override float minHeight => -1f;

		public override float flexibleHeight => -1f;

		public void Refresh()
		{
			updateFontAndText();
			RefreshScale();
		}

		protected override void OnPopulateMesh(VertexHelper toFill)
		{
			if (base.fontSize == 0)
			{
				toFill.Clear();
				return;
			}
			m_DisableDirty = true;
			if (base.font != null)
			{
				m_DisableFontTextureRebuiltCallback = true;
				base.cachedTextGenerator.Populate(IconDecoder.Decode(text), GetGenerationSettings(base.rectTransform.rect.size));
				Rect rect = base.rectTransform.rect;
				Vector2 textAnchorPivot = Text.GetTextAnchorPivot(base.alignment);
				Vector2 zero = Vector2.zero;
				zero.x = (((double)textAnchorPivot.x == 1.0) ? rect.xMax : rect.xMin);
				zero.y = (((double)textAnchorPivot.y == 0.0) ? rect.yMin : rect.yMax);
				Vector2 lhs = PixelAdjustPoint(zero) - zero;
				IList<UIVertex> verts = base.cachedTextGenerator.verts;
				float num = 1f / base.pixelsPerUnit;
				int num2 = verts.Count - 4;
				toFill.Clear();
				if (lhs != Vector2.zero)
				{
					for (int i = 0; i < num2; i++)
					{
						int num3 = i & 3;
						m_TempVerts[num3] = verts[i];
						m_TempVerts[num3].position *= num;
						m_TempVerts[num3].position.x += lhs.x;
						m_TempVerts[num3].position.y += lhs.y;
						if (num3 == 3)
						{
							toFill.AddUIVertexQuad(m_TempVerts);
						}
					}
				}
				else
				{
					for (int j = 0; j < num2; j++)
					{
						int num4 = j & 3;
						m_TempVerts[num4] = verts[j];
						m_TempVerts[num4].position *= num;
						if (num4 == 3)
						{
							toFill.AddUIVertexQuad(m_TempVerts);
						}
					}
				}
				m_DisableFontTextureRebuiltCallback = false;
			}
			m_DisableDirty = false;
		}

		public override void SetLayoutDirty()
		{
			if (!m_DisableDirty)
			{
				base.SetLayoutDirty();
			}
		}

		public override void SetVerticesDirty()
		{
			if (!m_DisableDirty)
			{
				base.SetVerticesDirty();
			}
		}

		public override void SetMaterialDirty()
		{
			if (!m_DisableDirty)
			{
				base.SetMaterialDirty();
			}
		}

		protected override void OnEnable()
		{
			base.OnEnable();
			base.alignment = TextAnchor.MiddleCenter;
			base.horizontalOverflow = HorizontalWrapMode.Overflow;
			base.verticalOverflow = VerticalWrapMode.Overflow;
			updateFontAndText();
			SetAllDirty();
		}

		protected override void OnDisable()
		{
			base.OnDisable();
			m_Tracker.Clear();
		}

		protected override void Start()
		{
			base.alignment = TextAnchor.MiddleCenter;
			base.horizontalOverflow = HorizontalWrapMode.Overflow;
			base.verticalOverflow = VerticalWrapMode.Overflow;
			updateFontAndText();
			SetAllDirty();
			UpdateMaterial();
			UpdateGeometry();
		}

		private void updateFontAndText()
		{
			if (vectorImageData != null)
			{
				base.font = vectorImageData.font;
				text = vectorImageData.glyph.unicode;
			}
		}

		private void RefreshScale()
		{
			if (materialUiScaler == null || !base.enabled)
			{
				return;
			}
			if (size == 0f && sizeMode == SizeMode.Manual)
			{
				base.fontSize = 0;
				return;
			}
			float num = size;
			if (sizeMode == SizeMode.Manual)
			{
				m_ScaledSize = num * materialUiScaler.scaler.scaleFactor;
			}
			else if (sizeMode == SizeMode.MatchWidth)
			{
				m_ScaledSize = base.rectTransform.rect.width;
				num = m_ScaledSize;
				m_ScaledSize *= materialUiScaler.scaler.scaleFactor;
			}
			else if (sizeMode == SizeMode.MatchHeight)
			{
				m_ScaledSize = base.rectTransform.rect.height;
				num = m_ScaledSize;
				m_ScaledSize *= materialUiScaler.scaler.scaleFactor;
			}
			else if (sizeMode == SizeMode.MatchMin)
			{
				Vector2 vector = new Vector2(base.rectTransform.rect.width, base.rectTransform.rect.height);
				m_ScaledSize = Mathf.Min(vector.x, vector.y);
				num = m_ScaledSize;
				m_ScaledSize *= materialUiScaler.scaler.scaleFactor;
			}
			else if (sizeMode == SizeMode.MatchMax)
			{
				Vector2 vector2 = new Vector2(base.rectTransform.rect.width, base.rectTransform.rect.height);
				m_ScaledSize = Mathf.Max(vector2.x, vector2.y);
				num = m_ScaledSize;
				m_ScaledSize *= materialUiScaler.scaler.scaleFactor;
			}
			if (m_ScaledSize > 500f)
			{
				m_LocalScaleFactor = m_ScaledSize / 500f;
			}
			else
			{
				m_LocalScaleFactor = 1f;
			}
			num *= m_LocalScaleFactor;
			base.fontSize = Mathf.RoundToInt(num);
			m_LocalScaleFactor *= size / Mathf.Max(size);
			if (m_LocalScaleFactor != float.NaN && new Vector3(m_LocalScaleFactor, m_LocalScaleFactor, m_LocalScaleFactor) != base.rectTransform.localScale)
			{
				m_Tracker.Add(this, base.rectTransform, DrivenTransformProperties.Scale);
				base.rectTransform.localScale = new Vector3(m_LocalScaleFactor, m_LocalScaleFactor, m_LocalScaleFactor);
			}
		}

		public override void CalculateLayoutInputHorizontal()
		{
			RefreshScale();
		}

		public override void CalculateLayoutInputVertical()
		{
			RefreshScale();
		}

		protected override void OnRectTransformDimensionsChange()
		{
			base.OnRectTransformDimensionsChange();
			RefreshScale();
		}
	}
}
